package learnPointer

import (
	"fmt"
	"reflect"
)

type T struct {
	name string
}

/**
1. 一个变量对应一个保存了变量对应类型值的内存空间
2. 一个指针的值是另一个变量的地址。
	一个指针对应变量在内存中的存储位置。
	并不是每一个值都会有一个内存地址，但是对于每一个变量必然有对应的内存地址。
	通过指针，我们可以直接读或更新对应变量的值，而不需要知道该变量的名字(如果变量有名字的话)。
*/

/*
1. 声明一个x变量
2. &x表达式(取x变量的内存地址)将产生一个指向该整数变量的指针,返回内存地址
3. 指针对应的数据类型是 *int ，指针被称之为“指向int类型的指针”
*/

func LearnPointer1() {
	x := 1
	p := &x // p, 类型是 *int // "1"
	*p = 2  // 等同于 x = 2  // "2"

	z := new(int)
	*z = 2
}

// *age ，指向变量age所在的内存单元
// &age，取出变量age所在内存地址，一般地址是十六进制。
func LearnPointer() {
	var v = T{
		name: string("222"),
	}
	// v 的类型为 T
	ptr := &v
	// v 代表被取地址的变量, &v 指向 v 在内存中的地址
	// 变量 v 的地址使用变量 ptr 进行接收，所以 ptr 的类型为 *T，称做 T 的指针类型，*代表指针
	fmt.Println(&v)
	fmt.Println(ptr)
	fmt.Println(*ptr)
	fmt.Println(reflect.TypeOf(ptr)) //  *learnPointer 也就是*T
	fmt.Println("======demo2====")
	//  变量、指针 和 地址三者的关系是，每个变量都拥有地址，指针的值就是地址
	//	当使用&操作符对普通变量进行取地址操作并得到变量的指针后，可以对指针使用*操作符，也就是指针取值
	//	取地址操作符&和取值操作符*是一对互补操作符，&取出地址，*根据地址取出地址指向的值
}

//指针: Go语言提供了指针。指针是一种直接存储了变量的内存地址的数据类型
